#pragma once

#ifndef Vector3SIMD_H
#define Vector3SIMD_H

//used to implement the common interface
#include "IVector3.h"

class Vector3SIMD : public IVector3
{
private:
	//the vector itself described as four float (the fourth one is always 0)
	__m128 _vector;

public:
	//constructor. Puts everything to 0.
	Vector3SIMD();

	//Constructor. Puts everything to the value of f.
	Vector3SIMD(float f);

	//Constructor. Set the value to x, y and z.
	Vector3SIMD(float x, float y, float z);

	//Destructor.
	~Vector3SIMD();

	//Get X
	inline float getX() const;

	//Get Y
	inline float getY() const;

	//Get Z
	inline float getZ() const;

	//Get W
	inline float getW() const;

	//new operator
	void* operator new(size_t);

	//new array operator
	void* operator new[](size_t);

	//delete operator
	void operator delete(void*);

	//delete array operator
	void operator delete[](void*);

	//cast _m128 operator
	inline operator __m128 () const;

	//setter (NOT COMMON)
	inline void set(__m128 v);

	//setter
	inline void set(float, float, float);

	//norme
	inline float getNorme() const;

};

//addition
extern inline void Vector3SIMDAdd(const Vector3SIMD&, const Vector3SIMD&, Vector3SIMD&);

//substract
extern inline void Vector3SIMDSub(const Vector3SIMD&, const Vector3SIMD&, Vector3SIMD&);

//multiplication
extern inline void Vector3SIMDMulF(const Vector3SIMD&, float f, Vector3SIMD&);

//multiplication
extern inline void Vector3SIMDMul(const Vector3SIMD&, const Vector3SIMD&, Vector3SIMD&);

//dot
extern inline float Vector3SIMDDot(const Vector3SIMD&, const Vector3SIMD&);

//normalize
extern inline void Vector3SIMDNormalize(const Vector3SIMD&, Vector3SIMD&);

//cross
extern inline void Vector3SIMDCross(const Vector3SIMD&, const Vector3SIMD&, Vector3SIMD&);

#endif